//
// Copyright 2017 Google Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// stylelint-disable selector-class-pattern --
// Selector '.mdc-*' should only be used in this project.

@use '@material/animation/functions' as animation-functions;
@use '@material/dom/dom';
@use '@material/feature-targeting/feature-targeting';
@use '@material/rtl/rtl';
@use '@material/theme/custom-properties';
@use '@material/theme/theme';
@use './linear-progress-theme';

/// @deprecated Use static-styles() and theme-styles() instead.
@mixin core-styles($query: feature-targeting.all()) {
  @include linear-progress-theme.bar-color(primary, $query: $query);
  @include linear-progress-theme.buffer-color(
    linear-progress-theme.$baseline-buffer-color,
    $query: $query
  );
  @include linear-progress-theme.bar-and-track-height(
    linear-progress-theme.$height,
    $query: $query
  );
  @include linear-progress-theme.buffering-keyframes(
    linear-progress-theme.$height,
    $query: $query
  );
  @include static-styles($query);
}

@mixin static-styles($query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);
  $feat-animation: feature-targeting.create-target($query, animation);

  @include feature-targeting.targets($feat-animation) {
    @include primary-indeterminate-translate-keyframes_;
    @include primary-indeterminate-scale-keyframes_;
    @include secondary-indeterminate-translate-keyframes_;
    @include secondary-indeterminate-scale-keyframes_;
    @include primary-indeterminate-translate-reverse-keyframes_;
    @include secondary-indeterminate-translate-reverse-keyframes_;
    @include buffering-reverse-keyframes_;
  }

  .mdc-linear-progress {
    @include feature-targeting.targets($feat-structure) {
      position: relative;
      width: 100%;
      transform: translateZ(0);
      // Create a border around the bar in Windows High Contrast Mode.
      outline: 1px solid transparent;
      overflow-x: hidden;

      @include dom.forced-colors-mode($exclude-ie11: true) {
        outline-color: CanvasText;
      }
    }

    @include feature-targeting.targets($feat-animation) {
      transition: animation-functions.exit-temporary(opacity, 250ms);
    }

    &__bar {
      @include feature-targeting.targets($feat-structure) {
        position: absolute;
        top: 0;
        bottom: 0;
        margin: auto 0; // Vertically center
        width: 100%;
        animation: none;
        transform-origin: top left;
      }

      @include feature-targeting.targets($feat-animation) {
        transition: animation-functions.exit-temporary(transform, 250ms);
      }
    }

    &__bar-inner {
      @include feature-targeting.targets($feat-structure) {
        display: inline-block;
        position: absolute;
        width: 100%;
        animation: none;
        // border-top is used rather than background-color to ensure that the
        // bar is visible in Windows High Contrast Mode.
        border-top-style: solid;
      }
    }

    &__buffer {
      @include feature-targeting.targets($feat-structure) {
        display: flex;
        position: absolute;
        top: 0;
        bottom: 0;
        margin: auto 0; // Vertically center
        width: 100%;
        overflow: hidden;
      }
    }

    &__buffer-dots {
      @include feature-targeting.targets($feat-structure) {
        background-repeat: repeat-x;
        flex: auto;
        @include rtl.ignore-next-line();
        transform: rotate(180deg);

        // Use SVG mask for non-IE11 browsers
        // SVG is optimized for data URI (https://codepen.io/tigt/post/optimizing-svgs-in-data-uris)
        $svg: "data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' enable-background='new 0 0 5 2' xml:space='preserve' viewBox='0 0 5 2' preserveAspectRatio='xMinYMin slice'%3E%3Ccircle cx='1' cy='1' r='1'/%3E%3C/svg%3E";
        -webkit-mask-image: url($svg);
        mask-image: url($svg);
      }

      @include feature-targeting.targets($feat-animation) {
        // stylelint-disable-next-line no-unknown-animations --
        // animation is in _linear-progress-theme.scss
        animation: mdc-linear-progress-buffering 250ms infinite linear;
      }
    }

    &__buffer-bar {
      @include feature-targeting.targets($feat-structure) {
        flex: 0 1 100%;
      }

      @include feature-targeting.targets($feat-animation) {
        transition: animation-functions.exit-temporary(flex-basis, 250ms);
      }
    }

    &__primary-bar {
      @include feature-targeting.targets($feat-structure) {
        transform: scaleX(0);
      }
    }

    &__secondary-bar {
      @include feature-targeting.targets($feat-structure) {
        display: none;
      }
    }

    @include indeterminate_($query: $query);

    @include rtl.rtl() {
      // The rtl() mixin does not account for nested `dir` attributes. Set
      // `dir` attribute on root to take highest priority.
      &:not([dir='ltr']) {
        @include _rtl-styles($query: $query);
      }
    }

    &--closed {
      @include feature-targeting.targets($feat-structure) {
        opacity: 0;
      }
    }

    &--closed-animation-off {
      .mdc-linear-progress__buffer-dots {
        @include feature-targeting.targets($feat-animation) {
          animation: none;
        }
      }

      &.mdc-linear-progress--indeterminate {
        .mdc-linear-progress__bar,
        .mdc-linear-progress__bar .mdc-linear-progress__bar-inner {
          @include feature-targeting.targets($feat-animation) {
            animation: none;
          }
        }
      }
    }
  }
}

// Private mixins.

@mixin indeterminate_($query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);
  $feat-animation: feature-targeting.create-target($query, animation);

  &--indeterminate {
    .mdc-linear-progress__bar {
      @include feature-targeting.targets($feat-structure) {
        transition: none;
      }
    }

    .mdc-linear-progress__primary-bar {
      @include feature-targeting.targets($feat-structure) {
        left: -145.166611%;
      }
    }

    .mdc-linear-progress__secondary-bar {
      @include feature-targeting.targets($feat-structure) {
        left: -54.888891%;
        display: block;
      }
    }

    &.mdc-linear-progress--animation-ready {
      .mdc-linear-progress__primary-bar {
        @include feature-targeting.targets($feat-animation) {
          animation: mdc-linear-progress-primary-indeterminate-translate 2s
            infinite linear;
        }

        > .mdc-linear-progress__bar-inner {
          @include feature-targeting.targets($feat-animation) {
            animation: mdc-linear-progress-primary-indeterminate-scale 2s
              infinite linear;
          }
        }
      }

      .mdc-linear-progress__secondary-bar {
        @include feature-targeting.targets($feat-animation) {
          animation: mdc-linear-progress-secondary-indeterminate-translate 2s
            infinite linear;
        }

        > .mdc-linear-progress__bar-inner {
          @include feature-targeting.targets($feat-animation) {
            animation: mdc-linear-progress-secondary-indeterminate-scale 2s
              infinite linear;
          }
        }
      }
    }
  }
}

@mixin _rtl-styles($query: $query) {
  $feat-structure: feature-targeting.create-target($query, structure);
  $feat-animation: feature-targeting.create-target($query, animation);

  .mdc-linear-progress__bar {
    @include feature-targeting.targets($feat-structure) {
      @include rtl.ignore-next-line();
      right: 0;
      @include rtl.ignore-next-line();
      -webkit-transform-origin: center right;
      @include rtl.ignore-next-line();
      transform-origin: center right;
    }
  }

  &.mdc-linear-progress--animation-ready {
    .mdc-linear-progress__primary-bar {
      @include feature-targeting.targets($feat-animation) {
        animation-name: mdc-linear-progress-primary-indeterminate-translate-reverse;
      }
    }

    .mdc-linear-progress__secondary-bar {
      @include feature-targeting.targets($feat-animation) {
        animation-name: mdc-linear-progress-secondary-indeterminate-translate-reverse;
      }
    }
  }

  .mdc-linear-progress__buffer-dots {
    @include feature-targeting.targets($feat-animation) {
      animation: mdc-linear-progress-buffering-reverse 250ms infinite linear;
    }

    @include feature-targeting.targets($feat-structure) {
      @include rtl.ignore-next-line();
      transform: rotate(0);
    }
  }

  &.mdc-linear-progress--indeterminate {
    .mdc-linear-progress__primary-bar {
      @include feature-targeting.targets($feat-structure) {
        @include rtl.ignore-next-line();
        right: -145.166611%;
        @include rtl.ignore-next-line();
        left: auto;
      }
    }

    .mdc-linear-progress__secondary-bar {
      @include feature-targeting.targets($feat-structure) {
        @include rtl.ignore-next-line();
        right: -54.888891%;
        @include rtl.ignore-next-line();
        left: auto;
      }
    }
  }
}

// Keyframes.

@mixin primary-indeterminate-translate-keyframes_ {
  @keyframes mdc-linear-progress-primary-indeterminate-translate {
    0% {
      transform: translateX(0);
    }

    20% {
      animation-timing-function: cubic-bezier(0.5, 0, 0.701732, 0.495819);
      transform: translateX(0);
    }

    59.15% {
      animation-timing-function: cubic-bezier(
        0.302435,
        0.381352,
        0.55,
        0.956352
      );

      $primary-half: custom-properties.create(
        --mdc-linear-progress-primary-half,
        83.67142%
      );
      @include apply-translate_($primary-half);
    }

    100% {
      $primary-full: custom-properties.create(
        --mdc-linear-progress-primary-full,
        200.611057%
      );
      @include apply-translate_($primary-full);
    }
  }
}

@mixin primary-indeterminate-scale-keyframes_ {
  @keyframes mdc-linear-progress-primary-indeterminate-scale {
    0% {
      transform: scaleX(0.08);
    }

    36.65% {
      animation-timing-function: cubic-bezier(0.334731, 0.12482, 0.785844, 1);
      transform: scaleX(0.08);
    }

    69.15% {
      animation-timing-function: cubic-bezier(0.06, 0.11, 0.6, 1);
      transform: scaleX(0.661479);
    }

    100% {
      transform: scaleX(0.08);
    }
  }
}

@mixin secondary-indeterminate-translate-keyframes_ {
  @keyframes mdc-linear-progress-secondary-indeterminate-translate {
    0% {
      animation-timing-function: cubic-bezier(0.15, 0, 0.515058, 0.409685);
      transform: translateX(0);
    }

    25% {
      animation-timing-function: cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);
      $secondary-quarter: custom-properties.create(
        --mdc-linear-progress-secondary-quarter,
        37.651913%
      );
      @include apply-translate_($secondary-quarter);
    }

    48.35% {
      animation-timing-function: cubic-bezier(0.4, 0.627035, 0.6, 0.902026);
      $secondary-half: custom-properties.create(
        --mdc-linear-progress-secondary-half,
        84.386165%
      );
      @include apply-translate_($secondary-half);
    }

    100% {
      $secondary-full: custom-properties.create(
        --mdc-linear-progress-secondary-full,
        160.277782%
      );
      @include apply-translate_($secondary-full);
    }
  }
}

@mixin secondary-indeterminate-scale-keyframes_ {
  @keyframes mdc-linear-progress-secondary-indeterminate-scale {
    0% {
      animation-timing-function: cubic-bezier(
        0.205028,
        0.057051,
        0.57661,
        0.453971
      );
      transform: scaleX(0.08);
    }

    19.15% {
      animation-timing-function: cubic-bezier(
        0.152313,
        0.196432,
        0.648374,
        1.004315
      );
      transform: scaleX(0.457104);
    }

    44.15% {
      animation-timing-function: cubic-bezier(
        0.257759,
        -0.003163,
        0.211762,
        1.38179
      );
      transform: scaleX(0.72796);
    }

    100% {
      transform: scaleX(0.08);
    }
  }
}

@mixin primary-indeterminate-translate-reverse-keyframes_ {
  @keyframes mdc-linear-progress-primary-indeterminate-translate-reverse {
    0% {
      transform: translateX(0);
    }

    20% {
      animation-timing-function: cubic-bezier(0.5, 0, 0.701732, 0.495819);
      transform: translateX(0);
    }

    59.15% {
      animation-timing-function: cubic-bezier(
        0.302435,
        0.381352,
        0.55,
        0.956352
      );
      $primary-half: custom-properties.create(
        --mdc-linear-progress-primary-half-neg,
        -83.67142%
      );
      @include apply-translate_($primary-half);
    }

    100% {
      $primary-full: custom-properties.create(
        --mdc-linear-progress-primary-full-neg,
        -200.611057%
      );
      @include apply-translate_($primary-full);
    }
  }
}

@mixin secondary-indeterminate-translate-reverse-keyframes_ {
  @keyframes mdc-linear-progress-secondary-indeterminate-translate-reverse {
    0% {
      animation-timing-function: cubic-bezier(0.15, 0, 0.515058, 0.409685);
      transform: translateX(0);
    }

    25% {
      animation-timing-function: cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);
      $secondary-quarter: custom-properties.create(
        --mdc-linear-progress-secondary-quarter-neg,
        -37.651913%
      );
      @include apply-translate_($secondary-quarter);
    }

    48.35% {
      animation-timing-function: cubic-bezier(0.4, 0.627035, 0.6, 0.902026);
      $secondary-half: custom-properties.create(
        --mdc-linear-progress-secondary-half-neg,
        -84.386165%
      );
      @include apply-translate_($secondary-half);
    }

    100% {
      $secondary-full: custom-properties.create(
        --mdc-linear-progress-secondary-full-neg,
        -160.277782%
      );
      @include apply-translate_($secondary-full);
    }
  }
}

@mixin buffering-reverse-keyframes_ {
  @keyframes mdc-linear-progress-buffering-reverse {
    from {
      @include rtl.ignore-next-line();
      transform: translateX(-10px);
    }
  }
}

@mixin apply-translate_($value) {
  @include theme.property(
    transform,
    translateX(value),
    $replace: (value: $value),
    $gss: (noflip: true)
  );
}
